import { app, shell, BrowserWindow, Notification, screen } from 'electron'
import icon from '../../../resources/icon.png?asset'
import { is } from '@electron-toolkit/utils'
import { join } from 'path'
import fs from 'fs'
import path from 'path';
import { spawn } from 'child_process';
import ffmpegPath from 'ffmpeg-static';
import BaseWindow from './components/BaseWindow'
import store from '../store/index'

export default class ScreenRecorderWindow extends BaseWindow {
  ffmpegProc: any = null;
  tempMp4Path: string = '';

  // 窗口
  width = 800
  height = 600

  // 拖拽相关
  initialX = 0
  initialY = 0
  winW = 0
  winH = 0
  // 创建窗口
  create(): void {
    const display = this.getDisplayByCursor()
    const x = display.workArea.x + Math.floor((display.workArea.width - this.width) / 2)
    const y = display.workArea.y + Math.floor((display.workArea.height - this.height) / 2)
  // 检查窗口是否已存在且未销毁
    if (this.frame !== null && !this.frame.isDestroyed()) {
      if (!this.frame.isVisible()) this.frame.show();
      this.setBounds( x, y, this.width, this.height)
      this.frame.focus()
      const language = store.get('language')
      const notification = new Notification({
        title: language === 'cn' ? '提示' : 'Tip',
        body: language === 'cn' ? '已打开屏幕录制，请勿重复打开！' : 'Screen recording has been turned on, please do not open it again!',
        silent: false, // 是否静音
      });

      notification.show();
      return
    }

    this.frame = new BrowserWindow({
      width: this.width,
      height: this.height,
      x,
      y,
      show: false,
      transparent: true,
      autoHideMenuBar: true,
      resizable: false,
      skipTaskbar: false, // 是否不显示任务栏
      alwaysOnTop: false, // 是否置顶
      icon,
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false, // 禁用沙箱模式
        zoomFactor: 1.0, // 禁止缩放
      },
    })

    // 窗口准备显示时，显示窗口
    this.frame.on('ready-to-show', () => {
      this.frame!.show()
    })

    // 设置窗口打开链接的处理方式
    this.frame.webContents.setWindowOpenHandler((details) => {
      shell.openExternal(details.url)
      return { action: 'deny' }
    })

    const routerPath = '/screenRecorder'
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      this.frame.loadURL(process.env['ELECTRON_RENDERER_URL'] + '/#' + routerPath)
    } else {
      this.frame.loadFile(join(__dirname, '../renderer/index.html'), {
        hash: routerPath
      })
    }
  }

  // 获取 ffmpeg 可执行文件路径
  getExePath() {
    if (app.isPackaged) {
      return join(process.resourcesPath, 'app.asar.unpacked', 'node_modules','ffmpeg-static', 'ffmpeg.exe');
    } else {
      return ffmpegPath;
    }
  }
  // 开始录制
  async startRecording() {
    const ffpPath = this.getExePath();
    if (!ffpPath) {
      throw new Error('未找到 ffmpeg 可执行文件');
    }

    // 临时 mp4 文件
    this.tempMp4Path = path.join(app.getPath('temp'), `recording-${Date.now()}.mp4`);

    // 启动 ffmpeg 子进程
    this.ffmpegProc = spawn(ffpPath as string, [
      '-y',                     // 覆盖输出
      '-f', 'webm',             // 输入格式是 webm
      '-i', 'pipe:0',           // 从 stdin 输入
      '-movflags', 'faststart',
      '-c:v', 'libx264',        // 编码为 mp4
      '-preset', 'ultrafast',   // 速度优先
      '-crf', '23',
      this.tempMp4Path
    ]);

    this.ffmpegProc.on('close', (code) => {
      console.log(`ffmpeg 进程退出，代码：${code}`);
    });

    this.ffmpegProc.stderr.on('data', (data) => {
      console.log(`ffmpeg: ${data}`);
    });
  }
  // 保存
  async saveVideo () {
    const settings = store.get('applicationSettings')
    const recordingDir = settings.recordingPath
    const filePath = join(recordingDir, `recording-${Date.now()}.mp4`)

    // const { filePath } = await dialog.showSaveDialog({
    //   buttonLabel: '保存视频',
    //   defaultPath: `recording-${Date.now()}.mp4`,
    //   filters: [
    //     { name: '视频文件', extensions: ['mp4'] },
    //     { name: '所有文件', extensions: ['*'] }
    //   ]
    // });

    const mp4Path = await this.stopRecording();

    if (!filePath || !mp4Path) {
      this.frame?.webContents.send('video-save-callback', 'cancel', '');
      return '';
    }

    try {
      await fs.promises.copyFile(mp4Path, filePath);
      fs.unlinkSync(mp4Path);
      this.frame?.webContents.send('video-save-callback', 'ok', filePath);
      return filePath
    } catch (e) {
      this.frame?.webContents.send('video-save-callback', 'error', filePath);
      return '';
    }
  }

  // 发送视频数据
  sendVideoData (data) {
    if (this.ffmpegProc && this.ffmpegProc.stdin.writable) {
      this.ffmpegProc.stdin.write(data);
    }
  }

  // 保存时停止录制
  async stopRecording (): Promise<string | null>{
    return new Promise((resolve) => {
      if (this.ffmpegProc) {
        this.ffmpegProc.stdin.end(); // 告诉 ffmpeg 输入结束
        this.ffmpegProc.on('exit', () => {
          resolve(this.tempMp4Path);
        });
      } else {
        resolve(null);
      }
    });
  }

  // 录制中的窗口设置
  setRecordingWindow () {
    this.frame?.setAlwaysOnTop(true)
    this.frame?.setSkipTaskbar(true)
  }

  // 录制结束后的窗口设置
  setEndWindow () {
    this.frame?.setAlwaysOnTop(false)
    this.frame?.setSkipTaskbar(false)
  }

  // 拖拽相关
  startDrag () {
    const point = screen.getCursorScreenPoint()
    const bounds = this.frame!.getContentBounds()
    this.initialX = point.x - bounds.x
    this.initialY = point.y - bounds.y
    this.winW = bounds.width
    this.winH = bounds.height
  }
  moveDrag(): void {
    const point = screen.getCursorScreenPoint() // 获取当前鼠标位置
    let x = point.x - this.initialX
    let y = point.y - this.initialY
    this.frame?.setBounds({ x, y, width: this.winW, height: this.winH })
  }
  stopDrag () {

  }

  getDisplayByCursor() {
    const cursorPoint = screen.getCursorScreenPoint() // 鼠标当前坐标
    return screen.getDisplayNearestPoint(cursorPoint) // 返回鼠标所在的屏幕
  }
}
